"""
代码评估专家智能体
评估候选人的编程能力和代码质量
"""

import asyncio
import re
import ast
import json
from typing import Dict, Any, List, Optional, Tuple
from datetime import datetime

from ...core.interfaces import AgentInterface, Task, TaskStatus, ToolInterface
from ..base_agent import BaseAgent
from ...core.container import container


class CodeEvaluationTool(ToolInterface):
    """代码评估工具"""
    
    def __init__(self):
        self._name = "code_evaluator"
        self.description = "Evaluate code quality, complexity, and programming skills"
        self.supported_languages = ["python", "javascript", "java", "cpp", "go", "rust"]
    
    @property
    def name(self) -> str:
        """工具名称"""
        return self._name
    
    async def execute(self, parameters: Dict[str, Any]) -> Dict[str, Any]:
        """执行代码评估"""
        code_content = parameters.get("code_content", "")
        language = parameters.get("language", "python").lower()
        evaluation_type = parameters.get("evaluation_type", "comprehensive")
        
        if not code_content:
            return {"error": "No code content provided"}
        
        if language not in self.supported_languages:
            return {"error": f"Unsupported language: {language}"}
        
        # 根据语言选择评估方法
        if language == "python":
            return await self._evaluate_python_code(code_content, evaluation_type)
        elif language == "javascript":
            return await self._evaluate_javascript_code(code_content, evaluation_type)
        else:
            return await self._evaluate_generic_code(code_content, language, evaluation_type)
    
    async def _evaluate_python_code(self, code: str, eval_type: str) -> Dict[str, Any]:
        """评估Python代码"""
        results = {
            "language": "python",
            "evaluation_type": eval_type,
            "metrics": {},
            "analysis": {},
            "suggestions": [],
            "overall_score": 0.0
        }
        
        try:
            # 1. 语法检查
            syntax_result = await self._check_python_syntax(code)
            results["metrics"]["syntax_score"] = syntax_result["score"]
            results["analysis"]["syntax"] = syntax_result
            
            # 2. 代码复杂度分析
            complexity_result = await self._analyze_code_complexity(code)
            results["metrics"]["complexity_score"] = complexity_result["score"]
            results["analysis"]["complexity"] = complexity_result
            
            # 3. 代码风格检查
            style_result = await self._check_code_style(code)
            results["metrics"]["style_score"] = style_result["score"]
            results["analysis"]["style"] = style_result
            
            # 4. 算法效率分析
            efficiency_result = await self._analyze_algorithm_efficiency(code)
            results["metrics"]["efficiency_score"] = efficiency_result["score"]
            results["analysis"]["efficiency"] = efficiency_result
            
            # 5. 最佳实践检查
            practices_result = await self._check_best_practices(code)
            results["metrics"]["practices_score"] = practices_result["score"]
            results["analysis"]["best_practices"] = practices_result
            
            # 6. 安全性检查
            security_result = await self._check_security_issues(code)
            results["metrics"]["security_score"] = security_result["score"]
            results["analysis"]["security"] = security_result
            
            # 计算综合评分
            weights = {
                "syntax_score": 0.20,
                "complexity_score": 0.15,
                "style_score": 0.15,
                "efficiency_score": 0.25,
                "practices_score": 0.15,
                "security_score": 0.10
            }
            
            overall_score = sum(
                results["metrics"][metric] * weight 
                for metric, weight in weights.items()
            )
            
            results["overall_score"] = overall_score
            
            # 生成改进建议
            results["suggestions"] = await self._generate_improvement_suggestions(results)
            
        except Exception as e:
            results["error"] = f"Code evaluation failed: {str(e)}"
        
        return results
    
    async def _check_python_syntax(self, code: str) -> Dict[str, Any]:
        """检查Python语法"""
        try:
            ast.parse(code)
            return {
                "score": 1.0,
                "status": "valid",
                "issues": []
            }
        except SyntaxError as e:
            return {
                "score": 0.0,
                "status": "invalid",
                "issues": [f"Syntax error at line {e.lineno}: {e.msg}"]
            }
    
    async def _analyze_code_complexity(self, code: str) -> Dict[str, Any]:
        """分析代码复杂度"""
        lines = code.split('\n')
        total_lines = len([line for line in lines if line.strip()])
        
        # 计算圈复杂度 (简化版)
        complexity_keywords = ['if', 'elif', 'else', 'for', 'while', 'try', 'except', 'with']
        complexity_count = 0
        
        for line in lines:
            for keyword in complexity_keywords:
                if keyword in line:
                    complexity_count += 1
        
        # 计算复杂度评分
        if complexity_count == 0:
            complexity_score = 1.0
        elif complexity_count <= 5:
            complexity_score = 0.9
        elif complexity_count <= 10:
            complexity_score = 0.7
        else:
            complexity_score = 0.5
        
        return {
            "score": complexity_score,
            "total_lines": total_lines,
            "complexity_count": complexity_count,
            "complexity_level": "low" if complexity_count <= 5 else "medium" if complexity_count <= 10 else "high"
        }
    
    async def _check_code_style(self, code: str) -> Dict[str, Any]:
        """检查代码风格"""
        issues = []
        score = 1.0
        
        lines = code.split('\n')
        
        # 检查缩进
        for i, line in enumerate(lines, 1):
            if line.strip() and not line.startswith(' ' * 4) and not line.startswith('\t'):
                if line.startswith(' '):
                    issues.append(f"Line {i}: Inconsistent indentation")
        
        # 检查变量命名
        variable_pattern = re.compile(r'\b([a-z][a-zA-Z0-9_]*)\s*=')
        for match in variable_pattern.finditer(code):
            var_name = match.group(1)
            if not var_name.islower() and '_' not in var_name:
                issues.append(f"Variable '{var_name}': Should use snake_case")
        
        # 检查函数命名
        function_pattern = re.compile(r'def\s+([a-zA-Z_][a-zA-Z0-9_]*)')
        for match in function_pattern.finditer(code):
            func_name = match.group(1)
            if not func_name.islower() and '_' not in func_name:
                issues.append(f"Function '{func_name}': Should use snake_case")
        
        # 检查行长度
        for i, line in enumerate(lines, 1):
            if len(line) > 88:
                issues.append(f"Line {i}: Line too long ({len(line)} > 88 characters)")
        
        # 根据问题数量计算评分
        score = max(0.0, 1.0 - len(issues) * 0.1)
        
        return {
            "score": score,
            "issues": issues,
            "issues_count": len(issues)
        }
    
    async def _analyze_algorithm_efficiency(self, code: str) -> Dict[str, Any]:
        """分析算法效率"""
        efficiency_issues = []
        score = 1.0
        
        # 检查常见的效率问题
        if re.search(r'for.*in.*range\(len\(', code):
            efficiency_issues.append("Use direct iteration instead of range(len())")
            score -= 0.1
        
        # 检查嵌套循环
        nested_loops = len(re.findall(r'for.*:\s*.*for.*:', code, re.MULTILINE))
        if nested_loops > 0:
            efficiency_issues.append(f"Found {nested_loops} nested loops - consider optimization")
            score -= nested_loops * 0.1
        
        # 检查字符串拼接
        if '+=' in code and 'str' in code:
            efficiency_issues.append("Consider using join() for string concatenation")
            score -= 0.05
        
        score = max(0.0, score)
        
        time_complexity = self._estimate_time_complexity(code)
        
        return {
            "score": score,
            "time_complexity": time_complexity,
            "efficiency_issues": efficiency_issues,
            "suggestions": ["Consider algorithmic improvements", "Profile code for bottlenecks"]
        }
    
    def _estimate_time_complexity(self, code: str) -> str:
        """估计时间复杂度"""
        # 简化的时间复杂度估计
        if 'for' in code and re.search(r'for.*for', code):
            return "O(n²)"
        elif 'for' in code or 'while' in code:
            return "O(n)"
        else:
            return "O(1)"
    
    async def _check_best_practices(self, code: str) -> Dict[str, Any]:
        """检查最佳实践"""
        practices_issues = []
        score = 1.0
        
        # 检查异常处理
        if 'try' not in code and ('open(' in code or 'requests.' in code):
            practices_issues.append("Missing exception handling for file/network operations")
            score -= 0.1
        
        # 检查文档字符串
        functions = re.findall(r'def\s+\w+\([^)]*\):', code)
        docstring_pattern = re.compile(r'def\s+\w+\([^)]*\):\s*"""')
        documented_functions = len(docstring_pattern.findall(code))
        
        if len(functions) > documented_functions:
            practices_issues.append("Functions should have docstrings")
            score -= 0.1
        
        # 检查常量使用
        if re.search(r'[^a-zA-Z_]([A-Z_]{2,})\s*=', code):
            score += 0.05  # 加分项
        
        score = max(0.0, min(1.0, score))
        
        return {
            "score": score,
            "issues": practices_issues,
            "good_practices": []
        }
    
    async def _check_security_issues(self, code: str) -> Dict[str, Any]:
        """检查安全问题"""
        security_issues = []
        score = 1.0
        
        # 检查危险函数使用
        dangerous_functions = ['eval', 'exec', 'input', '__import__']
        for func in dangerous_functions:
            if func + '(' in code:
                security_issues.append(f"Dangerous function used: {func}")
                score -= 0.2
        
        # 检查SQL注入风险
        if 'SELECT' in code.upper() and '+' in code:
            security_issues.append("Potential SQL injection risk")
            score -= 0.3
        
        # 检查硬编码密码
        if re.search(r'password\s*=\s*["\'][^"\']+["\']', code, re.IGNORECASE):
            security_issues.append("Hardcoded password detected")
            score -= 0.3
        
        score = max(0.0, score)
        
        return {
            "score": score,
            "security_issues": security_issues,
            "risk_level": "high" if score < 0.5 else "medium" if score < 0.8 else "low"
        }
    
    async def _generate_improvement_suggestions(self, results: Dict[str, Any]) -> List[str]:
        """生成改进建议"""
        suggestions = []
        
        if results["metrics"]["syntax_score"] < 1.0:
            suggestions.append("Fix syntax errors before proceeding")
        
        if results["metrics"]["complexity_score"] < 0.7:
            suggestions.append("Consider breaking down complex functions into smaller ones")
        
        if results["metrics"]["style_score"] < 0.8:
            suggestions.append("Follow PEP 8 style guidelines")
        
        if results["metrics"]["efficiency_score"] < 0.7:
            suggestions.append("Optimize algorithm complexity and data structure usage")
        
        if results["metrics"]["practices_score"] < 0.8:
            suggestions.append("Add proper error handling and documentation")
        
        if results["metrics"]["security_score"] < 0.8:
            suggestions.append("Review and fix security vulnerabilities")
        
        return suggestions
    
    async def _evaluate_javascript_code(self, code: str, eval_type: str) -> Dict[str, Any]:
        """评估JavaScript代码"""
        # JavaScript代码评估的简化实现
        return {
            "language": "javascript",
            "evaluation_type": eval_type,
            "overall_score": 0.8,
            "metrics": {
                "syntax_score": 0.9,
                "style_score": 0.8,
                "efficiency_score": 0.7
            },
            "suggestions": ["Add proper error handling", "Use modern ES6+ features"]
        }
    
    async def _evaluate_generic_code(self, code: str, language: str, eval_type: str) -> Dict[str, Any]:
        """通用代码评估"""
        lines = len(code.split('\n'))
        score = 0.7  # 基础评分
        
        return {
            "language": language,
            "evaluation_type": eval_type,
            "overall_score": score,
            "metrics": {
                "lines_of_code": lines,
                "estimated_score": score
            },
            "suggestions": [f"Detailed {language} evaluation not yet implemented"]
        }


class CodeEvaluatorAgent(BaseAgent):
    """代码评估专家智能体"""
    
    def __init__(self):
        capabilities = [
            "code_quality_analysis",
            "algorithm_efficiency_evaluation", 
            "programming_skill_assessment",
            "code_review_automation",
            "technical_interview_support"
        ]
        super().__init__("代码评估专家", capabilities)
        self.agent_id = "code_evaluator"
        self.description = "专业的代码质量评估和编程能力分析专家"
        self.tools = [CodeEvaluationTool()]
    
    async def _initialize_agent_specific(self):
        """智能体特定的初始化逻辑"""
        # 这里可以添加代码评估专家的特定初始化逻辑
        pass
    
    async def can_handle_task(self, task: Task) -> bool:
        """检查是否可以处理任务"""
        return task.task_type in ["code_evaluation", "code_analysis", "github_analysis", "technical_review"]
    
    async def _process_task_internal(self, task: Task) -> Dict[str, Any]:
        """内部任务处理逻辑"""
        try:
            # 从任务描述中提取代码内容
            code_content = task.metadata.get("code_content", task.description)
            language = task.metadata.get("programming_language", "python")
            evaluation_type = task.metadata.get("evaluation_type", "comprehensive")
            
            # 执行代码评估
            code_tool = self.tools[0] if self.tools else CodeEvaluationTool()
            evaluation_result = await code_tool.execute({
                "code_content": code_content,
                "language": language,
                "evaluation_type": evaluation_type
            })
            
            return {
                "agent": self.name,
                "task_type": task.task_type,
                "evaluation_result": evaluation_result,
                "processed_at": datetime.now().isoformat(),
                "status": "completed"
            }
            
        except Exception as e:
            return {
                "agent": self.name,
                "error": str(e),
                "status": "failed"
            }
    
    async def process_task(self, task: Task) -> Task:
        """处理代码评估任务"""
        try:
            task.status = TaskStatus.IN_PROGRESS
            
            # 从任务描述中提取代码内容
            code_content = task.metadata.get("code_content", task.description)
            language = task.metadata.get("programming_language", "python")
            evaluation_type = task.metadata.get("evaluation_type", "comprehensive")
            
            # 执行代码评估
            code_tool = self.tools[0]
            evaluation_result = await code_tool.execute({
                "code_content": code_content,
                "language": language,
                "evaluation_type": evaluation_type
            })
            
            # 生成综合分析报告
            analysis_report = await self._generate_analysis_report(evaluation_result, task.metadata)
            
            task.result = analysis_report
            task.status = TaskStatus.COMPLETED
            
        except Exception as e:
            task.result = {"error": f"Code evaluation failed: {str(e)}"}
            task.status = TaskStatus.FAILED
        
        return task
    
    async def _generate_analysis_report(self, evaluation_result: Dict[str, Any], metadata: Dict[str, Any]) -> Dict[str, Any]:
        """生成分析报告"""
        
        candidate_name = metadata.get("candidate_name", "Unknown")
        position = metadata.get("target_position", "Developer")
        
        # 基于评估结果生成技能评级
        skill_rating = await self._calculate_skill_rating(evaluation_result)
        
        # 生成面试建议
        interview_suggestions = await self._generate_interview_suggestions(evaluation_result)
        
        # 预测编程潜力
        programming_potential = await self._assess_programming_potential(evaluation_result)
        
        report = {
            "candidate_info": {
                "name": candidate_name,
                "target_position": position,
                "evaluation_date": datetime.now().isoformat()
            },
            "code_evaluation": evaluation_result,
            "skill_assessment": {
                "programming_skills": skill_rating,
                "strengths": self._identify_strengths(evaluation_result),
                "weaknesses": self._identify_weaknesses(evaluation_result),
                "skill_level": self._determine_skill_level(evaluation_result["overall_score"])
            },
            "programming_potential": programming_potential,
            "interview_recommendations": interview_suggestions,
            "hiring_recommendation": self._generate_hiring_recommendation(evaluation_result, programming_potential),
            "development_suggestions": evaluation_result.get("suggestions", [])
        }
        
        return report
    
    async def _calculate_skill_rating(self, evaluation_result: Dict[str, Any]) -> Dict[str, float]:
        """计算技能评级"""
        metrics = evaluation_result.get("metrics", {})
        
        return {
            "code_quality": metrics.get("style_score", 0.0) * 100,
            "algorithm_design": metrics.get("efficiency_score", 0.0) * 100,
            "best_practices": metrics.get("practices_score", 0.0) * 100,
            "security_awareness": metrics.get("security_score", 0.0) * 100,
            "overall_programming": evaluation_result.get("overall_score", 0.0) * 100
        }
    
    def _identify_strengths(self, evaluation_result: Dict[str, Any]) -> List[str]:
        """识别技术优势"""
        strengths = []
        metrics = evaluation_result.get("metrics", {})
        
        if metrics.get("syntax_score", 0) >= 0.9:
            strengths.append("语法掌握扎实")
        
        if metrics.get("style_score", 0) >= 0.8:
            strengths.append("代码风格规范")
        
        if metrics.get("efficiency_score", 0) >= 0.8:
            strengths.append("算法效率意识强")
        
        if metrics.get("practices_score", 0) >= 0.8:
            strengths.append("遵循最佳实践")
        
        if metrics.get("security_score", 0) >= 0.8:
            strengths.append("安全编程意识")
        
        return strengths
    
    def _identify_weaknesses(self, evaluation_result: Dict[str, Any]) -> List[str]:
        """识别技术不足"""
        weaknesses = []
        metrics = evaluation_result.get("metrics", {})
        
        if metrics.get("syntax_score", 1) < 0.7:
            weaknesses.append("语法错误较多")
        
        if metrics.get("style_score", 1) < 0.6:
            weaknesses.append("代码风格不规范")
        
        if metrics.get("efficiency_score", 1) < 0.6:
            weaknesses.append("算法效率有待提升")
        
        if metrics.get("practices_score", 1) < 0.6:
            weaknesses.append("缺乏最佳实践应用")
        
        if metrics.get("security_score", 1) < 0.6:
            weaknesses.append("安全编程意识不足")
        
        return weaknesses
    
    def _determine_skill_level(self, overall_score: float) -> str:
        """确定技能水平"""
        if overall_score >= 0.9:
            return "专家级 (Expert)"
        elif overall_score >= 0.8:
            return "高级 (Senior)"
        elif overall_score >= 0.7:
            return "中级 (Intermediate)"
        elif overall_score >= 0.6:
            return "初级 (Junior)"
        else:
            return "入门级 (Beginner)"
    
    async def _generate_interview_suggestions(self, evaluation_result: Dict[str, Any]) -> List[str]:
        """生成面试建议"""
        suggestions = []
        overall_score = evaluation_result.get("overall_score", 0.0)
        
        if overall_score >= 0.8:
            suggestions.extend([
                "可以问一些高级算法和设计模式问题",
                "讨论系统架构和性能优化",
                "探讨代码重构和团队协作经验"
            ])
        elif overall_score >= 0.6:
            suggestions.extend([
                "重点考察基础算法和数据结构",
                "询问代码调试和问题解决经验", 
                "了解学习能力和成长潜力"
            ])
        else:
            suggestions.extend([
                "从基础语法和概念开始考察",
                "提供简单的编程题目",
                "评估学习意愿和培训需求"
            ])
        
        return suggestions
    
    async def _assess_programming_potential(self, evaluation_result: Dict[str, Any]) -> Dict[str, Any]:
        """评估编程潜力"""
        metrics = evaluation_result.get("metrics", {})
        analysis = evaluation_result.get("analysis", {})
        
        # 潜力指标计算
        learning_potential = (metrics.get("syntax_score", 0) + metrics.get("practices_score", 0)) / 2
        problem_solving = metrics.get("efficiency_score", 0)
        code_quality_awareness = metrics.get("style_score", 0)
        
        potential_score = (learning_potential * 0.4 + problem_solving * 0.4 + code_quality_awareness * 0.2)
        
        return {
            "potential_score": potential_score * 100,
            "learning_ability": learning_potential * 100,
            "problem_solving": problem_solving * 100,
            "quality_awareness": code_quality_awareness * 100,
            "growth_prediction": self._predict_growth_trajectory(potential_score),
            "recommended_development_path": self._suggest_development_path(evaluation_result)
        }
    
    def _predict_growth_trajectory(self, potential_score: float) -> str:
        """预测成长轨迹"""
        if potential_score >= 0.8:
            return "高潜力，预期快速成长为技术专家"
        elif potential_score >= 0.6:
            return "中等潜力，通过培训可稳步提升"
        else:
            return "需要基础培训，成长需要更多时间和指导"
    
    def _suggest_development_path(self, evaluation_result: Dict[str, Any]) -> List[str]:
        """建议发展路径"""
        suggestions = []
        metrics = evaluation_result.get("metrics", {})
        
        if metrics.get("efficiency_score", 0) < 0.7:
            suggestions.append("加强算法和数据结构学习")
        
        if metrics.get("practices_score", 0) < 0.7:
            suggestions.append("学习软件工程最佳实践")
        
        if metrics.get("security_score", 0) < 0.7:
            suggestions.append("提升安全编程意识")
        
        suggestions.extend([
            "参与开源项目贡献",
            "进行代码复审和同行学习",
            "定期技术分享和知识输出"
        ])
        
        return suggestions
    
    def _generate_hiring_recommendation(self, evaluation_result: Dict[str, Any], potential_assessment: Dict[str, Any]) -> Dict[str, Any]:
        """生成招聘建议"""
        overall_score = evaluation_result.get("overall_score", 0.0)
        potential_score = potential_assessment.get("potential_score", 0.0) / 100
        
        # 综合评分 (当前能力70% + 潜力30%)
        composite_score = overall_score * 0.7 + potential_score * 0.3
        
        if composite_score >= 0.8:
            recommendation = "强烈推荐"
            reason = "编程能力强，发展潜力大"
        elif composite_score >= 0.7:
            recommendation = "推荐"
            reason = "具备基本要求，有提升空间"
        elif composite_score >= 0.6:
            recommendation = "谨慎考虑"
            reason = "能力有限，需要大量培训"
        else:
            recommendation = "不推荐"
            reason = "编程基础薄弱，不符合岗位要求"
        
        return {
            "recommendation": recommendation,
            "composite_score": composite_score * 100,
            "reasoning": reason,
            "conditions": self._get_recommendation_conditions(composite_score)
        }
    
    def _get_recommendation_conditions(self, score: float) -> List[str]:
        """获取推荐条件"""
        if score >= 0.8:
            return ["可直接安排重要项目", "适合技术领导角色"]
        elif score >= 0.7:
            return ["需要1-2个月适应期", "配备导师指导"]
        elif score >= 0.6:
            return ["需要3-6个月培训期", "从简单任务开始"]
        else:
            return ["建议先进行基础培训", "考虑实习岗位"]
    
    async def get_capabilities(self) -> List[str]:
        """获取智能体能力"""
        return self.capabilities
    
    async def get_status(self) -> Dict[str, Any]:
        """获取智能体状态"""
        return {
            "agent_id": self.agent_id,
            "name": self.name,
            "status": "active",
            "supported_languages": self.tools[0].supported_languages,
            "capabilities": self.capabilities
        }